home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Carousel
/
CAROUSEL.cdr
/
mactosh
/
ed
/
billiard.sit
/
Billiard Parlour.Help
next >
Wrap
Text File
|
1988-10-30
|
13KB
|
263 lines
General Operation
Each game has a CUE BALL, except Billiards has two. A cue ball may be
launched with the mouse. This is done by placing the mouse near the ball,
pressing, then dragging out a cue line. The ball is launched upon release
of the mouse button, with speed proportional to the dragged length of the
cue line and direction determined by the line. No ball other than cue
ball(s) may be shot; for Billiards the launched ball is always the one
closest to the initial press-down point of the mouse.
Be careful not to shoot too hard - if you 'slam' a nearby object ball, you
may get a 'hop' and not hit the object solidly. A little practice will
reveal this.
You can arrange balls by holding down the Option key of the keyboard while
you press on, and subsequently drag, a ball. A menu item 'Arrange Balls'
also performs this function, but must be deselected after arrangement is
complete.
>>
A hand-cursor results whenever balls may be arranged. Sunk
balls deposited near the bottom of the screen can be moved back onto the
table without recourse to the Option key or menu.
ENGLISH is invoked by selecting same on the Options menu, upon which a
picture of the cue ball face appears to the right of the table. The white
spot shows where the next shot will strike the cue ball. Note two things:
the spot reverts to the default position after each shot, and this default
lies at the theoretical zero-english height of 7/5 radius.
The collision sounds may be turned on or off via the Options menu item
'Sound'. Likewise, 'English' has the effect of hiding or bringing
back the English display. This menu item does not affect the value of
English, which in any case always reverts to zero after any shot.
>>
Scoring may be performed with the 100-carrom scoring rack atop the screen.
When using the carroms, simply drag carroms to and fro. The TURN SCORE is
always reported in the central display just below the carrom rack. This
is the number of balls sunk on the previous turn. For straightforward
turns the number will be the amount to add into the current player's
cumulative score. For scratches, etc. one has to carefully apply whatever
scoring rules have been agreed upon; in such cases the central display is
intended as a guide, not an actual score.
SCRATCHES are reported (as beeps) when the cue ball is sunk, or in
8-ball when the 8 is sunk. For cue ball scratches, the ball is placed
in the right-hand half of the table, at an open location. As usual the
cue ball may be moved with the Option key or the Options menu entry
'Arrange Balls'.
>>
The Games
In BILLIARDS the players alternate between the spotted and unspotted cue
balls. A score is logged on the central display when the current cue ball
strikes the other two object balls, but only if three rails are hit
by the cue ball before the second object ball is struck.
In STRAIGHT POOL the rack is numbered consecutively from 1 through 15, and
sunk balls will be deposited in numerical order.
In 8-BALL the rack has a central 8 ball, with a certain pattern of solids
and stripes surrounding, and sunk balls are deposited with solids to the
left and stripes to the right. There are many different 'favorite' 8-Ball
rack configurations: the one chosen for this program guarantees a fairly
even distribution of stripe/solid placement over a number of breaks.
>>
In 9-BALL the rack has a central 9 ball, with a certain pattern of balls 1
through 8 surrounding. Sunk balls are deposited in numerical order.
In SNOOKER there are fifteen unmarked balls in the rack, with numbered
balls 2,3,4,5,6,7 in specific places. Sunk balls are deposited in two
groups: numbered and unmarked.
In SLOP there are optional rack sizes, and all object balls are unmarked.
The LAG game simply automates the 'lagging' process in which players
alternately launch a cue ball to see who can come closer to a point or
rail. As with other options, players may choose their own lag criteria,
with the program providing decision aid - in this case a lag line is drawn
on the screen to indicate final cue ball position. The lag also has the
feature that the cue ball may be either dragged or shot while the item is
checked. NOTE: This item must be deselected to enable any other game.
>>
The Racks
The menu items 'Complete Rack' and 'Continuation Rack' provide means for
setting up games. 'Complete Rack' is used to start afresh. 'Continuation
Rack' makes the most sense in Straight Pool variations, by racking all but
the final ball left on the table. If the number of object balls left is
less than or greater than one, or if the single ball left is within the
15-ball racking triangle the Complete Rack results as a default.
>>
Magnification
This is to aid in reading ball numbers and assessing complex positions.
Glass: A rectangle will follow the mouse movements. Hold down the
mouse button to magnify the selected area. An <Option>-Click
or a Double-click will cause the magnifying glass to disappear.
FullScreen: The table is blown up to greater than full-screen size.
Drag the mouse, with the button held down, to scroll the
full screen display (as in MacPaint 'ShowPage' mode). An
<Option>-Click or a Double-click will cause the screen
to revert to normal.
Note: The startup display (with animated Billiard Parlour scene) may be
speeded up by holding down the <Option> key.
~~
Origins of Billiard Parlour
The project was started as a sharp test of Rascal animation. We had
worked out fast 'integer calculus' routines for colliding bodies and
performing various rapid graphics functions. These formulas and techniques
coupled with bit-copying of ball images formed the basis for
the reasonably realistic billiard effects. The final application was thus
written entirely within the Rascal compiler/development system
environment.
The following technical remarks may be of interest to the serious
programmer.
>>
Perhaps the most salient fact about the billiards algorithms is that no
floating point is used whatsoever. All calculations are done in 16-bit
integer format. The reason, of course, is the quest for speed. Though
floating point variables are easier to work with for dynamical problems,
there is no hope for full pool table dynamics on the Macintosh unless
integer calculations predominate.
>>
The speed of the integer dynamical routines should be evident from a
consideration of what must be done to iterate an entire ensemble of hard
spheres. Say there are N spheres total in motion on the table. One must
on every pass of the main iteration loop
1) Update 2N coordinate values.
2) Update 2N velocity values.
3) Seek and analyze collisions, requiring N*N/2 checks.
4) Handle damping and English.
5) For most games, check for pocket sinking for each of the N balls.
6) Check for rail bounces for each of N balls.
Naturally, some of the above are interrelated - for example collision and
damping are what imply the need for updating velocities. The fact that
N*N/2 checks are used to seek all collisions is especially cumbersome when
the number N in the ensemble is large. For a full pool table, this means
128 checks for collisions are made at each iteration.
>>
An example of trickery intended to optimize speed is that used to check
for collisions. The Rascal source has a collision algorithm essentially
like so:
s := 4*radius*radius;
loop(,i:=0,++i,i>numballs-1)
{
loop(i<numballs-1, j:=i+1, ++j, j>numballs-1)
{
dx := x[i] - x[j];
if dx*dx <= s then
{ dy:= y[i] - y[j];
if dx*dx + dy*dy <= s then
collide(i,j);
};
};
};
>>
The two loops are straightforward, dictating that we are checking for
pair (i,j) collisions where i is not equal to j. But the primary point is
that the check dx*dx<s is made first to save time. Note that two balls
have collided (that is, penetrate each other) whenever
sqrt(dx*dx + dy*dy) <= 2*radius
so collision also implies sqrt(dx*dx)< 2*radius. The 'sqrt' function can
be dropped, as in the explicit loop above, in the interest of speed.
Many such integer calculations were necessary to achieve a certain
realism.
>>
Other examples which might interest the programmer are:
1) Each ball has two pictures, which alternate after every multiple
of pi*radius is moved on the screen. This gives an impression of
rolling.
2) Damping is hard to accomplish with integers. The primary problem
is that if we attempt at each iteration something like:
vx[i]:= (vx[i]*999)/1000;
vy[i]:= (vy[i]*999)/1000;
then, in general, one of vx or vy will vanish completely before
the other, at the tail end of a ball's motion. This causes
swerving at the end of the trajectory, as a ball disappointingly
follows one axis or the other. The solution was to apply the
formula only at certain times - not in each iteration - and make
sure that total damping is achieved before the final swerve. This
last effect is done by simply stopping the motion after a certain
iteration count which depends in turn on the game played and on
other conditions.
>>
3) The difficulty with integer calculus is evident when one considers
the basic Newtonian iteration:
x[i]:= x[i] + vx[i];
y[i]:= y[i] + vy[i];
noting that in real-number calculus one would have each velocity
term multiplied by a small time increment dt. Because we cannot
do this with integers (the smallest increment being 1) there is
the threat that balls will move very far at each iteration. The
solution is easy enough: hold all coordinates and velocities as
large integers, and divide by a constant only when actually
graphing. Thus in Billiard Parlour the typical coordinates are on
the order of 10000 and divisions by 100 are typical at graph time.
>>
4) The problem of English is a good example of a tough-sounding
problem which turns out to be rather trivial to solve. For English
effects at a rail, we add to the reflected velocity the following
cross- product expression:
k(omega X velocity)
where omega is a unit vector normal to the plane of the table and
indicating angular rotation, while k is the value of (horizontal)
English. For vertical English at a rail, we simply add to the normal
reflected component Vn the quantity h*Vn where h is now the vertical
English. These rules are not completely exact physically, but it is
easy to show that the major qualitative behavior of English at rails
is handled correctly with these simple calculations. For English
during ball-ball encounters, the same formula are used, but relegated
of course to the center-of-momentum frame, where each ball sees in
effect the other ball as a 'rail'.
>>
5) Billiard Parlour dynamical calculations are not exact, and for the
sake of speed some 'molecular' effects - in which balls stick
together momentarily - have been left in. These effects occur
primarily because of the ambiguity between incoming and outgoing
collisions: if two balls mutually penetrate, it is not easy to
find out whether they have just had their velocities reflected, or
whether now is the time to so reflect. The ambiguity is
especially fierce when many balls are banging around in a clutch.
So the application was designed for speed: there is a molecule
from time to time, but the molecule does not stay together.
Removing all unrealistic effects proves to take too much compute
time away from the otherwise pleasing motion.
>>
The serious programmer may also be interested in the various utilities and
methods unrelated to dynamics that went into the project. The
magnification feature for reading balls and positions easily is a good
example of Rascal off-screen port graphics. The sound of ball clicks is
achieved by free-form synthesis of 'chirp' waves - i.e. high-frequency,
brief tone bursts. The graphics problem presented by the carroms scoring
rack is surprisingly difficult, and stands as a good example of straight
quickdraw methods.
The key graphics procedures are found on the standard Rascal Jan 1986
release as library entries. The key library is called __GraphUtils, and
has many things from screen initialization to high-speed sine, cosine, and
square root functions; in general integer techniques for fast graphics.
But other libraries are involved heavily - the interested programmer can
consult the Billiard Parlour source listing in conjunction with the Rascal
User Manual.